﻿using System;
using System.Collections.Generic;
using EnterpriseFramework.DataAccess.Provider;

namespace EnterpriseFramework.DataAccess
{
    public class ELAdapter<T>
    {
        private static DicCache<Table> cache = new DicCache<Table>(25);
        private DALAdapter<T> dalAdapter;

        public ELAdapter()
        {
            dalAdapter = new DALAdapter<T>();
        }

        public IDataCollection<T> dataCollection { get; set; }

        #region - Transaction -

        public void BeginTransaction()
        {
            dalAdapter.provider.BeginTransaction();
        }

        public void Rollback()
        {
            dalAdapter.provider.Rollback();
        }

        public void Commit()
        {
            dalAdapter.provider.Commit();
        }

        #endregion

        /// <summary>
        /// Gets a table model for given type.
        /// </summary>
        /// <param name="type">type</param>
        /// <returns>table model</returns>
        private Table GetTable(Type type)
        {
            Table table = cache.Get(type.FullName);
            if (table == null)
            {
                table = TableFactory.Build(type);
                cache.Put(type.FullName, table);
            }
            return table;
        }

        /// <summary>
        /// Used to get select all from database depend on T typed.
        /// </summary>
        /// <returns>Return List of T type where T represent Entity Type that you can retruned.</returns>
        public IDataCollection<T> Select()
        {
            //1- get Field Name And Data type From TableAttribute
            Type type = typeof(T);
            //MemberInfo member = type;
            //TableAttribute tableAtribute = (TableAttribute)member.GetCustomAttributes(true)[0];
            //StringBuilder selectAll = new StringBuilder(200).Append("SELECT ");

            //StringBuilder columns = new StringBuilder();
            //foreach (PropertyInfo property in typeof(T).GetProperties())
            //{
            //    ColumnAttribute columnAttribute = (ColumnAttribute)property.GetCustomAttributes(true)[0];
            //    columns.Append(columnAttribute.Name).Append(",");
            //}
            //columns.Remove(columns.Length - 1, 1);
            //selectAll.Append(columns).Append(" FROM ").Append(tableAtribute.Schema).Append(".[")
            //    .Append(tableAtribute.Name).Append("]");
            ////b.ToString().Substring(0,b.ToString().IndexOf(" FROM"))
            //if (columns.Length <= 0)
            //{
            //    columns = selectAll;
            //    columns.Replace("SELECT ", "");
            //    columns.Remove(columns.ToString().IndexOf(" FROM"), columns.Length - columns.ToString().IndexOf(" FROM"));
            //}
            //columns.ToString().Split(new char[] { ',' });

            Table table = GetTable(type);
            IDataCollection<T> list = dalAdapter.Select(table, null);

            return list;
        }
        public IDataCollection<T> Select(Query query)
        {
            Type type = typeof(T);
            Table table = GetTable(type);
            IDataCollection<T> list = dalAdapter.Select(table, query);
            return list;
        }
        public List<T> Select(object ByObject)
        {
            List<T> dd = new List<T>();
            return dd;
        }

        public int Insert<T>(T InsertedObject)
        {

            return 0;
        }

        public int Insert<T>(T InsertedObject, object ByObject)
        {
            return 0;
        }

        public int Delete<T>(T DeletedObject)
        {
            return 0;
        }

        public int Delete<T>(T DeletedObject, object ByObject)
        {
            return 0;
        }

        public int Update<T>(T UpdatedObject)
        {
            return 0;
        }

        public int Update<T>(T UpdatedObject, object ByObject)
        {
            return 0;
        }

        public void ExecuteNonQueryDBObject(object ExeObject)
        {

        }

        public object ExecuteScaleDBObject(object ExeObject)
        {

            return null;
        }

        public T ExecuteReaderDBObject(object ExeObject)
        {


            return (T)new object();
        }
    }
}
